package com.black.platform.codeType.service.impl;

import com.black.common.vo.MenuVo;
import com.black.platform.codeType.service.CodeTypeService;
import com.black.platform.codeType.vo.CodeTypeSearchVo;
import com.black.platform.codeType.vo.CodeTypeVo;
import com.black.platform.dictionary.po.Dictionary;
import com.black.platform.dictionary.po.DictionaryCategory;
import com.black.platform.dictionary.service.handler.DictionaryCategoryHandlerService;
import com.black.platform.dictionary.service.handler.DictionaryHandlerService;
import com.black.platform.menu.service.handler.MenuHandlerService;
import com.black.platform.organization.service.handler.OrganizationHandlerService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author linwenfeng
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class CodeTypeServiceImpl implements CodeTypeService {

    private final DictionaryHandlerService dictionaryHandlerService;

    private final MenuHandlerService menuHandlerService;

    private final DictionaryCategoryHandlerService dictionaryCategoryHandlerService;

    private final OrganizationHandlerService organizationHandlerService;


    @Override
    public List<CodeTypeVo> search(CodeTypeSearchVo searchVo) {
        List<CodeTypeVo> codeTypeVoList = new ArrayList<>();
        if ("Menu".equals(searchVo.getCodeType())) {
            List<MenuVo> menuVoList = menuHandlerService.search(searchVo.getFilter().get("systemCode").toString());
            menuVoList.forEach(menuVo -> {
                CodeTypeVo codeTypeVo = new CodeTypeVo();
                recurrenceSetData(menuVo, codeTypeVo);
                codeTypeVoList.add(codeTypeVo);
            });
        } else if ("dictionaryCategory".equals(searchVo.getCodeType())) {
            List<DictionaryCategory> allCategory = dictionaryCategoryHandlerService.getAllCategory();
            allCategory.forEach(item -> {
                CodeTypeVo codeTypeVo = new CodeTypeVo();
                codeTypeVo.setId(item.getCodeType());
                codeTypeVo.setLabel(item.getName());
                codeTypeVoList.add(codeTypeVo);
            });
        } else if ("organization".equals(searchVo.getCodeType())) {
            return organizationHandlerService.getOrganizationVoTree();
        } else {
            List<Dictionary> dictionaryList = dictionaryHandlerService.getByCodeType(searchVo.getCodeType(), false);
            return buildCodeTypeSelectTree(dictionaryList);

        }
        return codeTypeVoList;
    }

    private void recurrenceSetData(MenuVo menuVo, CodeTypeVo codeTypeVo) {
        if (menuVo != null && codeTypeVo != null) {
            codeTypeVo.setId(menuVo.getId());
            codeTypeVo.setLabel(menuVo.getTitle());
            if (menuVo.getChildren() != null && menuVo.getChildren().size() > 0) {
                List<CodeTypeVo> children = new ArrayList<>();
                codeTypeVo.setChildren(children);
                menuVo.getChildren().forEach(menuVo1 -> {
                    CodeTypeVo codeTypeVo1 = new CodeTypeVo();
                    recurrenceSetData(menuVo1, codeTypeVo1);
                    children.add(codeTypeVo1);
                });
            }
        }
    }

    /***
     * 构建数据字典树
     * @param dictionaryList 数据字典集合
     * @return 数据字典树集
     */
    private List<CodeTypeVo> buildCodeTypeSelectTree(List<Dictionary> dictionaryList) {
        List<CodeTypeVo> voList = new ArrayList<>();
        Map<String, CodeTypeVo> voMap = dictionaryList.stream().collect(Collectors.toMap(Dictionary::getCode, codeType -> {
            CodeTypeVo dictionaryTreeVo = new CodeTypeVo();
            dictionaryTreeVo.setId(codeType.getCode());
            dictionaryTreeVo.setLabel(codeType.getName());
            return dictionaryTreeVo;
        }));
        dictionaryList.sort(Comparator.comparingInt(Dictionary::getOrders));
        for (Dictionary dictionary : dictionaryList) {
            if (StringUtils.isEmpty(dictionary.getParentCode())) {
                voList.add(voMap.get(dictionary.getCode()));
            } else {
                CodeTypeVo dictionaryTreeVo = voMap.get(dictionary.getParentCode());
                if (dictionaryTreeVo != null) {
                    if (dictionaryTreeVo.getChildren() == null) {
                        dictionaryTreeVo.setChildren(new ArrayList<>());
                    }
                    dictionaryTreeVo.getChildren().add(voMap.get(dictionary.getCode()));
                } else {
                    voList.add(voMap.get(dictionary.getCode()));
                }
            }
        }
        return voList;
    }
}
